/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.app.manager;

import lombok.extern.slf4j.Slf4j;

/**
 * 类加载器预热器
 * 已过期，请使用{@link io.iec.edp.caf.msu.common.loader.ClassPreloader} 替换
 * @author Leon Huo
 */
@Slf4j
@Deprecated
public class ClassPreloader {
//    private final String suName;
//    //名称过滤器
//    private ClassNameFilter classNameFilter;
//
//    //包名前缀
//    private final String[] packages;
//
//    //URLClasspath
//    private final URLClassPath urlClassPath;
//
//    //需处理的类名
//    private final List<String> classNames = new ArrayList<>();
//
//    //类加载器
//    private final ClassLoader classLoader;

    private final io.iec.edp.caf.msu.common.loader.ClassPreloader preloader;

    /**
     * 构造方法 需传入指定的SU名称以及要扫描的包名
     * <p>
     *
     * @param suName 微服务单元名称
     * @param packages 包集合
     */
    @Deprecated
    public ClassPreloader(String suName, String... packages) {
//        this.packages = packages;
//        this.suName = suName.toLowerCase();
////        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//
////        boolean ifParallel = System.getProperty("parallel.startup", "false").equals("true");
////        //非并行启动
////        if (!ifParallel) {
////            this.urlClassPath = ((CAFClassLoader) classLoader).getSuClasspath(this.suName);
////            this.classLoader = classLoader;
////        } else {
////            //并行启动-
////            this.urlClassPath = ((PlatformClassloader) classLoader).getSuClasspath(this.suName);
////            this.classLoader = classLoader.getParent();
////        }
//        this.classLoader = AppManager.getCafClassLoader(CafEnvironment.getStartupMode());
//        this.urlClassPath = AppManager.getSuClasspath(this.suName);
        this.preloader = new io.iec.edp.caf.msu.common.loader.ClassPreloader(suName,packages);
    }

    /**
     * 支持传入一个类名称过滤器
     *
     * @param suName 微服务单元名称
     * @param classNameFilter 过滤器
     * @param packages  包集合
     */
    @Deprecated
    public ClassPreloader(String suName, ClassNameFilter classNameFilter, String... packages) {
//        this.classNameFilter = classNameFilter;
//        this.packages = packages;
//        this.suName = suName.toLowerCase();
////        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
////        boolean ifParallel = System.getProperty("parallel.startup", "false").equals("true");
////        //非并行启动
////        if (!ifParallel) {
////            this.urlClassPath = ((CAFClassLoader) classLoader).getSuClasspath(this.suName);
////            this.classLoader = classLoader;
////        } else {
////            this.urlClassPath = ((PlatformClassloader) classLoader).getSuClasspath(this.suName);
////            this.classLoader = classLoader.getParent();
////        }
//        this.classLoader = AppManager.getCafClassLoader(CafEnvironment.getStartupMode());
//        this.urlClassPath = AppManager.getSuClasspath(this.suName);
        this.preloader = new io.iec.edp.caf.msu.common.loader.ClassPreloader(suName,classNameFilter,packages);
    }

//    private void init() {
//        //todo 临时处理
//        if (this.classLoader == null) {
//            return;
//        }
//
//        long startTime = System.currentTimeMillis();
//
//        for (String nowPackage : packages) {
//            String nowPackageDir = nowPackage.replace('.', '/');
//            try {
//                Enumeration<Resource> resources = this.urlClassPath.getResources(nowPackageDir);
//
//                while (resources.hasMoreElements()) {
//                    URL url = resources.nextElement().getURL();
//
//                    // 获取jar
//                    String protocol = url.getProtocol();
//                    if ("jar".equals(protocol)) {
//                        JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
//                        //扫描jar包文件 并添加到集合中
//                        classNames.addAll(findClassesByJar(nowPackage, jar));
//                    }
//                }
//            } catch (IOException e) {
//                log.info("Class PreLoader init failed.", e);
//            }
//        }
//
//        long timeCost = System.currentTimeMillis() - startTime;
//        log.info("ClassPreLoader initialized in " + timeCost + "ms.");
//    }
//
//    private List<String> findClassesByJar(String pkgName, JarFile jar) {
//        List<String> result = new ArrayList<>();
//        String pkgDir = pkgName.replace(".", "/");
//
//        Enumeration<JarEntry> entry = jar.entries();
//
//        JarEntry jarEntry;
//        String name, className;
//        //遍历JAR包
//        while (entry.hasMoreElements()) {
//            jarEntry = entry.nextElement();
//            name = jarEntry.getName();
//            // 如果是以/开头的 获取后面的字符串
//            if (name.charAt(0) == '/') {
//                name = name.substring(1);
//            }
//
//            if (jarEntry.isDirectory() || !name.startsWith(pkgDir) || !name.endsWith(".class")) {
//                continue;
//            }
//
//            //匹配到class 转换真正的类名
//            className = name.substring(0, name.length() - 6).replace('/', '.');
//            if (classNameFilter == null || classNameFilter.doFilter(className)) {
//                result.add(className);
//            }
//        }
//
//        return result;
//    }

    @Deprecated
    public void startPreload() {
        this.preloader.startPreload();
//        //todo 临时处理
//        if (this.classLoader == null) {
//            return;
//        }
//
//        Thread thread = new Thread(() -> {
//            if (urlClassPath != null) {
//                init();
//            }
//
//            long startTime = System.currentTimeMillis();
//            int count = 0;
//            for (String s : classNames) {
//                try {
//                    Class.forName(s, false, this.classLoader);
//                    Thread.yield();
//                    count++;
//                } catch (NoClassDefFoundError | ClassNotFoundException error) {
//                    log.info("Can't find class during preloading. " + error.getClass());
//                }
//            }
//
//            long timeCost = System.currentTimeMillis() - startTime;
//            log.info("Service Unit: " + suName + " " + count + " class loaded in " + timeCost + "ms.");
//        });
//
//        thread.start();
    }

}
